#include "gc.h"
#include "itkImageRegionConstIteratorWithIndex.h"

// Extract components from a label image to generate a layer
void generateLayer (LabelImage::Pointer labelImage, Layer& layer)
{
  itk::ImageRegionConstIteratorWithIndex<LabelImage> 
    itr(labelImage, labelImage->GetLargestPossibleRegion());
  LabelPixel maxLabel = 0;
  while (!itr.IsAtEnd()) {
    if (itr.Get() > maxLabel) {
      maxLabel = itr.Get();
    }
    ++itr;
  }
  layer.components.reserve(maxLabel + 1);
  for (int componentNo = 0; componentNo <= maxLabel; componentNo++) {
    Component component(componentNo, false);
    layer.components.push_back(component);
  }
  int imageWidth = labelImage->GetLargestPossibleRegion().GetSize()[0];
  int imageHeight = labelImage->GetLargestPossibleRegion().GetSize()[1];
  for (itr.GoToBegin(); !itr.IsAtEnd(); ++itr) {
    int label = itr.Get();
    int x = itr.GetIndex()[0];
    int y = itr.GetIndex()[1];
    Point point(x, y);
    layer.components[label].points.push_back(point);
    if (x == 0 || x == imageWidth - 1 || y == 0 || y == imageHeight - 1) {
      layer.components[label].isOnBoundary = true;
    }
  }
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Generate a volume from a bunch of label images
void generateVolume (std::vector<std::string> paths, Volume& volume, 
		     VerboseLevel verbose)
{
  int layerNum = paths.size();
  volume.layers.reserve(layerNum);
  for (int layerNo = 0; layerNo < layerNum; layerNo++) {
    LabelImage::Pointer labelImage = NULL;
    Layer layer(layerNo, labelImage);
    volume.layers.push_back(layer);
  }
#ifdef USE_OMP
#pragma omp parallel for
#endif
  for (int layerNo = 0; layerNo < layerNum; layerNo++) {
    volume.layers[layerNo].labelImage = readLabelImage(paths[layerNo].c_str());
    generateLayer(volume.layers[layerNo].labelImage, volume.layers[layerNo]);
    if (verbose == VERBOSE_HIGH) {
      std::cout << "Generate volume: generate layer " 
		<< layerNo << " done." << std::endl;
    }
  }
}
